using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using ECommerce.Web.HtmlHelpers;
using Machine.Specifications;

namespace Html_element_identity_specs
{
    [Subject("Html element identity")]
    public class When_getting_the_html_element_identity_for_a_property
    {
        private static Expression<Func<Entity1, int>> expression;

        Establish context = () =>
            {
                expression = x => x.Property1;
            };

        It should_return_a_valid_name = () =>
            {
                string result = HtmlElementIdentityHelper.NameFor(expression);

                result.ShouldEqual("Entity1.Property1");
            };

        It should_return_a_valid_id = () =>
            {
                string result = HtmlElementIdentityHelper.IdFor(expression);

                result.ShouldEqual("Entity1_Property1");
            };
    }

    [Subject("Html element identity")]
    public class When_getting_the_html_element_identity_for_a_property_chain
    {
        private static Expression<Func<Entity1, int>> expression;

        Establish context = () =>
            {
                expression = x => x.Entity2.Property1;
            };

        It should_return_a_valid_name = () =>
            {
                string result = HtmlElementIdentityHelper.NameFor(expression);

                result.ShouldEqual("Entity1.Entity2.Property1");
            };

        It should_return_a_valid_id = () =>
            {
                string result = HtmlElementIdentityHelper.IdFor(expression);

                result.ShouldEqual("Entity1_Entity2_Property1");
            };
    }

    [Subject("Html element identity")]
    public class When_getting_the_html_element_identity_for_a_property_via_a_collection
    {
        private static Expression<Func<Entity1, int>> expression;

        Establish context = () =>
            {
                int index = 0;

                expression = x => x.Entity2Collection[index].Property1;
            };

        It should_return_a_valid_name = () =>
            {
                string result = HtmlElementIdentityHelper.NameFor(expression);

                result.ShouldEqual("Entity1.Entity2Collection[0].Property1");
            };

        It should_return_a_valid_id = () =>
            {
                string result = HtmlElementIdentityHelper.IdFor(expression);

                result.ShouldEqual("Entity1_Entity2Collection_0__Property1");
            };
    }

    [Subject("Html element identity")]
    public class When_getting_the_html_element_identity_for_a_property_via_chained_collections
    {
        private static Expression<Func<Entity1, int>> expression;

        Establish context = () =>
            {
                int index1 = 0;
                int index2 = 1;

                expression = x => x.Entity2Collection[index1].Entity3Collection[index2].Property1;
            };

        It should_return_a_valid_name = () =>
            {
                string result = HtmlElementIdentityHelper.NameFor(expression);

                result.ShouldEqual("Entity1.Entity2Collection[0].Entity3Collection[1].Property1");
            };

        It should_return_a_valid_id = () =>
            {
                string result = HtmlElementIdentityHelper.IdFor(expression);

                result.ShouldEqual("Entity1_Entity2Collection_0__Entity3Collection_1__Property1");
            };
    }

    public class Entity1
    {
        public int Property1 { get; set; }

        public Entity2 Entity2 { get; set; }

        public Entity1()
        {
            Entity2Collection = new List<Entity2>();
        }

        public IList<Entity2> Entity2Collection { get; set; }
    }

    public class Entity2
    {
        public int Property1 { get; set; }

        public Entity2()
        {
            Entity3Collection = new List<Entity3>();
        }

        public IList<Entity3> Entity3Collection { get; set; }
    }

    public class Entity3
    {
        public int Property1 { get; set; }
    }
}